home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / math / ast53src.zip / XSCREEN.C < prev   
C/C++ Source or Header  |  1996-09-29  |  53KB  |  1,841 lines

  1. /*
  2. ** Astrolog (Version 5.30) File: xscreen.c
  3. **
  4. ** IMPORTANT NOTICE: The graphics database and chart display routines
  5. ** used in this program are Copyright (C) 1991-1996 by Walter D. Pullen
  6. ** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
  7. ** Permission is granted to freely use and distribute these routines
  8. ** provided one doesn't sell, restrict, or profit from them in any way.
  9. ** Modification is allowed provided these notices remain with any
  10. ** altered or edited versions of the program.
  11. **
  12. ** The main planetary calculation routines used in this program have
  13. ** been Copyrighted and the core of this program is basically a
  14. ** conversion to C of the routines created by James Neely as listed in
  15. ** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
  16. ** available from Matrix Software. The copyright gives us permission to
  17. ** use the routines for personal use but not to sell them or profit from
  18. ** them in any way.
  19. **
  20. ** The PostScript code within the core graphics routines are programmed
  21. ** and Copyright (C) 1992-1993 by Brian D. Willoughby
  22. ** (brianw@sounds.wa.com). Conditions are identical to those above.
  23. **
  24. ** The extended accurate ephemeris databases and formulas are from the
  25. ** calculation routines in the program "Placalc" and are programmed and
  26. ** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
  27. ** (alois@azur.ch). The use of that source code is subject to
  28. ** regulations made by Astrodienst Zurich, and the code is not in the
  29. ** public domain. This copyright notice must not be changed or removed
  30. ** by any user of this program.
  31. **
  32. ** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
  33. ** X Window graphics initially programmed 10/23-29/1991.
  34. ** PostScript graphics initially programmed 11/29-30/1992.
  35. ** Last code change made 9/22/1996.
  36. */
  37.  
  38. #include "astrolog.h"
  39.  
  40.  
  41. #ifdef GRAPH
  42. /*
  43. ******************************************************************************
  44. ** Astrolog Icon.
  45. ******************************************************************************
  46. */
  47.  
  48. #ifdef X11
  49. /* This information used to define Astrolog's X icon (Rainbow over Third */
  50. /* Eye) is identical to the output format used by the bitmap program.    */
  51. /* You could extract this section and run xsetroot -bitmap on it.        */
  52.  
  53. #define icon_width 63
  54. #define icon_height 32
  55. static char icon_bits[] = {
  56.  0x00,0x00,0x00,0xa8,0x0a,0x00,0x00,0x00,0x00,0x00,0x40,0x55,0x55,0x01,0x00,
  57.  0x00,0x00,0x00,0xa8,0xaa,0xaa,0x0a,0x00,0x00,0x00,0x00,0x54,0xf5,0x57,0x15,
  58.  0x00,0x00,0x00,0x80,0xaa,0xaa,0xaa,0xaa,0x00,0x00,0x00,0x40,0xd5,0xff,0xff,
  59.  0x55,0x01,0x00,0x00,0xa0,0xaa,0xaa,0xaa,0xaa,0x02,0x00,0x00,0x50,0xfd,0xff,
  60.  0xff,0x5f,0x05,0x00,0x00,0xa8,0xaa,0x2a,0xaa,0xaa,0x0a,0x00,0x00,0xd4,0xff,
  61.  0xaf,0xfa,0xff,0x15,0x00,0x00,0xaa,0x2a,0x00,0x00,0xaa,0x2a,0x00,0x00,0xf5,
  62.  0xbf,0xaa,0xaa,0xfe,0x57,0x00,0x80,0xaa,0x02,0x00,0x00,0xa0,0xaa,0x00,0x40,
  63.  0xfd,0xab,0xfa,0xaf,0xea,0x5f,0x01,0xa0,0xaa,0x80,0xff,0xff,0x80,0xaa,0x02,
  64.  0x50,0xff,0xea,0xff,0xff,0xab,0x7f,0x05,0xa0,0x2a,0xf0,0xff,0xff,0x07,0xaa,
  65.  0x02,0xd0,0xbf,0xfa,0x0f,0xf8,0xaf,0x7e,0x05,0xa8,0x0a,0xfc,0x01,0xc0,0x1f,
  66.  0xa8,0x0a,0xd4,0xaf,0x7e,0x00,0x00,0xbf,0xfa,0x15,0xa8,0x0a,0x3f,0x00,0x00,
  67.  0x7e,0xa8,0x0a,0xf4,0xaf,0x1f,0xe0,0x03,0xfc,0xfa,0x15,0xaa,0x82,0x0f,0xdc,
  68.  0x1d,0xf8,0xa0,0x2a,0xf4,0xab,0x07,0x23,0x62,0xf0,0xea,0x17,0xaa,0xc2,0x87,
  69.  0x91,0xc4,0xf0,0xa1,0x2a,0xf4,0xeb,0xc3,0xd0,0x85,0xe1,0xeb,0x17,0xaa,0xe0,
  70.  0x83,0x91,0xc4,0xe0,0x83,0x2a,0xf5,0xeb,0x03,0x23,0x62,0xe0,0xeb,0x57,0xaa,
  71.  0xe0,0x01,0xdc,0x1d,0xc0,0x83,0x2a,0xf5,0xeb,0x01,0xe0,0x03,0xc0,0xeb,0x57,
  72.  0xaa,0xe0,0x01,0x00,0x00,0xc0,0x83,0x2a,0xfd,0xeb,0x01,0x00,0x00,0xc0,0xeb,
  73.  0x5f};
  74. #endif
  75.  
  76.  
  77. /*
  78. ******************************************************************************
  79. ** Interactive Screen Graphics Routines.
  80. ******************************************************************************
  81. */
  82.  
  83. /* Set up all the colors used by the program, i.e. the foreground and   */
  84. /* background colors, and all the colors in the object arrays, based on */
  85. /* whether or not we are in monochrome and/or reverse video mode.       */
  86.  
  87. void InitColorsX()
  88. {
  89.   int i;
  90. #ifdef X11
  91.   Colormap cmap;
  92.   XColor xcol;
  93.  
  94.   if (!gi.fFile) {
  95.     cmap = XDefaultColormap(gi.disp, gi.screen);
  96.  
  97.     /* Allocate a color from the present X11 colormap. Given a string like */
  98.     /* "violet", allocate this color and return a value specifying it.     */
  99.  
  100.     for (i = 0; i < 16; i++) {
  101.       XParseColor(gi.disp, cmap, szColorX[i], &xcol);
  102.       XAllocColor(gi.disp, cmap, &xcol);
  103.       rgbind[i] = xcol.pixel;
  104.     }
  105.   }
  106. #endif
  107.   gi.kiOn   = kMainA[!gs.fInverse];
  108.   gi.kiOff  = kMainA[gs.fInverse];
  109.   gi.kiLite = gs.fColor ? kMainA[2+gs.fInverse] : gi.kiOn;
  110.   gi.kiGray = gs.fColor ? kMainA[3-gs.fInverse] : gi.kiOn;
  111.   for (i = 0; i <= 8; i++)
  112.     kMainB[i]    = gs.fColor ? kMainA[i]    : gi.kiOn;
  113.   for (i = 0; i <= 7; i++)
  114.     kRainbowB[i] = gs.fColor ? kRainbowA[i] : gi.kiOn;
  115.   for (i = 0; i < 4; i++)
  116.     kElemB[i]    = gs.fColor ? kElemA[i]    : gi.kiOn;
  117.   for (i = 0; i <= cAspect; i++)
  118.     kAspB[i]     = gs.fColor ? kAspA[i]     : gi.kiOn;
  119.   for (i = 0; i <= cObj; i++)
  120.     kObjB[i]     = gs.fColor ? kObjA[i]     : gi.kiOn;
  121. #ifdef X11
  122.   if (!gi.fFile) {
  123.     XSetBackground(gi.disp, gi.gc,   rgbind[gi.kiOff]);
  124.     XSetForeground(gi.disp, gi.pmgc, rgbind[gi.kiOff]);
  125.   }
  126. #endif
  127. }
  128.  
  129.  
  130. #ifdef ISG
  131. /* This routine opens up and initializes a window and prepares it to be */
  132. /* drawn upon, and gets various information about the display, too.     */
  133.  
  134. void BeginX()
  135. {
  136. #ifdef X11
  137.   gi.disp = XOpenDisplay(gs.szDisplay);
  138.   if (gi.disp == NULL) {
  139.     PrintError("Can't open display.");
  140.     Terminate(tcFatal);
  141.   }
  142.   gi.screen = DefaultScreen(gi.disp);
  143.   bg = BlackPixel(gi.disp, gi.screen);
  144.   fg = WhitePixel(gi.disp, gi.screen);
  145.   hint.x = gi.xOffset; hint.y = gi.yOffset;
  146.   hint.width = gs.xWin; hint.height = gs.yWin;
  147.   hint.min_width = BITMAPX1; hint.min_height = BITMAPY1;
  148.   hint.max_width = BITMAPX;  hint.max_height = BITMAPY;
  149.   hint.flags = PPosition | PSize | PMaxSize | PMinSize;
  150. #if FALSE
  151.   wmhint = XGetWMHints(gi.disp, gi.wind);
  152.   wmhint->input = True;
  153.   XSetWMHints(gi.disp, gi.wind, wmhint);
  154. #endif
  155.   gi.depth = DefaultDepth(gi.disp, gi.screen);
  156.   if (gi.depth < 5) {
  157.     gi.fMono = fTrue;      /* Is this a monochrome monitor? */
  158.     gs.fColor = fFalse;
  159.   }
  160.   gi.root = RootWindow(gi.disp, gi.screen);
  161.   if (gs.fRoot)
  162.     gi.wind = gi.root;     /* If -XB in effect, we'll use the root window. */
  163.   else
  164.     gi.wind = XCreateSimpleWindow(gi.disp, DefaultRootWindow(gi.disp),
  165.       hint.x, hint.y, hint.width, hint.height, 5, fg, bg);
  166.   gi.pmap = XCreatePixmap(gi.disp, gi.wind, gs.xWin, gs.yWin, gi.depth);
  167.   gi.icon = XCreateBitmapFromData(gi.disp, DefaultRootWindow(gi.disp),
  168.     icon_bits, icon_width, icon_height);
  169.   if (!gs.fRoot)
  170.     XSetStandardProperties(gi.disp, gi.wind, szAppName, szAppName, gi.icon,
  171.       (char **)xkey, 0, &hint);
  172.  
  173.   /* We have two graphics workareas. One is what the user currently sees in */
  174.   /* the window, and the other is what we are currently drawing on. When    */
  175.   /* done, we can quickly copy this to the viewport for a smooth look.      */
  176.  
  177.   gi.gc = XCreateGC(gi.disp, gi.wind, 0, 0);
  178.   XSetGraphicsExposures(gi.disp, gi.gc, 0);
  179.   gi.pmgc = XCreateGC(gi.disp, gi.wind, 0, 0);
  180.   InitColorsX();                                  /* Go set up colors. */
  181.   if (!gs.fRoot)
  182.     XSelectInput(gi.disp, gi.wind, KeyPressMask | StructureNotifyMask |
  183.       ExposureMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask);
  184.   XMapRaised(gi.disp, gi.wind);
  185.   XSync(gi.disp, 0);
  186.   XFillRectangle(gi.disp, gi.pmap, gi.pmgc, 0, 0, gs.xWin, gs.yWin);
  187. #endif /* X11 */
  188.  
  189. #ifdef WIN
  190.   if (wi.fChartWindow && (wi.xClient != gs.xWin ||
  191.     wi.yClient != gs.yWin) && wi.hdcPrint == hdcNil)
  192.     ResizeWindowToChart();
  193.   gi.xOffset = NMultDiv(wi.xClient - gs.xWin, wi.xScroll, nScrollDiv);
  194.   gi.yOffset = NMultDiv(wi.yClient - gs.yWin, wi.yScroll, nScrollDiv);
  195.   SetWindowOrg(wi.hdc, -gi.xOffset, -gi.yOffset);
  196.   SetWindowExt(wi.hdc, wi.xClient, wi.yClient);
  197.   SetMapMode(wi.hdc, MM_ANISOTROPIC);
  198.   SelectObject(wi.hdc, GetStockObject(NULL_PEN));
  199.   SelectObject(wi.hdc, GetStockObject(NULL_BRUSH));
  200.   if (!gs.fJetTrail || wi.hdcPrint != hdcNil)
  201.     PatBlt(wi.hdc, -gi.xOffset, -gi.yOffset, wi.xClient, wi.yClient,
  202.       gs.fInverse ? WHITENESS : BLACKNESS);
  203.   InitColorsX();
  204. #endif /* WIN */
  205.  
  206. #ifdef MSG
  207.   if (!FValidResmode(gi.nRes))    /* Initialize graphics mode to hi-res. */
  208.     gi.nRes = gs.nResHi;
  209.   _setvideomode(gi.nRes == -1 ? _VRES16COLOR : gi.nRes);
  210.   if (_grstatus()) {
  211.     PrintError("Can't enter graphics mode.");
  212.     Terminate(tcFatal);
  213.   }
  214.   _getvideoconfig((struct videoconfig far *) &gi.cfg);
  215.   if (gi.cfg.numcolors < 16) {
  216.     gi.fMono  = fTrue;
  217.     gs.fColor = fFalse;
  218.   }
  219.   _remapallpalette((long FPTR *) rgb);
  220.   _setactivepage(0);
  221.   _setvisualpage(0);
  222.   InitColorsX();
  223. #ifdef MOUSE
  224.   MouseInit(xPcScreen, yPcScreen);
  225. #endif
  226.   /* Make sure we reset textrows upon restart. */
  227.   gs.nTextRows = abs(gs.nTextRows);
  228. #endif /* MSG */
  229.  
  230. #ifdef BGI
  231.   int i;
  232.   static struct palettetype pal;
  233.  
  234.   if (!FValidResmode(gi.nRes))    /* Initialize graphics mode to hi-res. */
  235.     gi.nRes = gs.nResHi;
  236.   if (!gi.fLoaded) {
  237.     registerfarbgidriver(ATT_driver_far);      /* attf.obj     */
  238.     registerfarbgidriver(CGA_driver_far);      /* cgaf.obj     */
  239.     registerfarbgidriver(EGAVGA_driver_far);   /* egavgaf.obj  */
  240.     registerfarbgidriver(Herc_driver_far);     /* hercf.obj    */
  241.     registerfarbgidriver(IBM8514_driver_far);  /* ibm8514f.obj */
  242.     registerfarbgidriver(PC3270_driver_far);   /* pc3270f.obj  */
  243.     gi.nDriver = DETECT;
  244.     initgraph(&gi.nDriver, &gi.nGraph, "");
  245.     gi.fLoaded = fTrue;
  246.   }
  247.   if (gi.nRes <= 0) {
  248.     switch (gi.nDriver) {
  249.     case CGA:      gi.nGraph = CGAHI;      break;
  250.     case MCGA:     gi.nGraph = MCGAHI;     break;
  251.     case EGA:      gi.nGraph = EGAHI;      break;
  252.     case EGA64:    gi.nGraph = EGA64HI;    break;
  253.     case EGAMONO:  gi.nGraph = EGAMONOHI;  break;
  254.     case HERCMONO: gi.nGraph = HERCMONOHI; break;
  255.     case ATT400:   gi.nGraph = ATT400HI;   break;
  256.     case VGA:      gi.nGraph = VGAHI;      break;
  257.     case PC3270:   gi.nGraph = PC3270HI;   break;
  258.     case IBM8514:  gi.nGraph = IBM8514HI;  break;
  259.     default:       gi.nGraph = 0;
  260.     }
  261.   } else {
  262.     switch (gi.nDriver) {
  263.     case CGA:      gi.nGraph = CGAHI;      break;
  264.     case MCGA:     gi.nGraph = MCGAHI;     break;
  265.     case EGA:      gi.nGraph = EGAHI;      break;
  266.     case EGA64:    gi.nGraph = EGA64HI;    break;
  267.     case EGAMONO:  gi.nGraph = EGAMONOHI;  break;
  268.     case HERCMONO: gi.nGraph = HERCMONOHI; break;
  269.     case ATT400:   gi.nGraph = ATT400HI;   break;
  270.     case VGA:      gi.nGraph = VGAMED;     break;
  271.     case PC3270:   gi.nGraph = PC3270HI;   break;
  272.     case IBM8514:  gi.nGraph = IBM8514LO;  break;
  273.     default:       gi.nGraph = 0;
  274.     }
  275.   }
  276.   setgraphmode(gi.nGraph);
  277.   if (graphresult()) {
  278.     PrintError("Can't enter graphics mode.");
  279.     Terminate(tcFatal);
  280.   }
  281.   gi.nPages = 1 + (gi.nDriver == HERCMONO ||
  282.     (gi.nDriver == VGA && gi.nGraph != VGAHI) || gi.nDriver == EGA);
  283.   if (getmaxcolor()+1 < 16) {
  284.     gi.fMono  = fTrue;
  285.     gs.fColor = fFalse;
  286.   }
  287.   getpalette(&pal);
  288.   for (i = 0; i < pal.size; i++)
  289.     pal.colors[i] = (char)rgb[i];
  290.   setallpalette(&pal);
  291.   setactivepage(0);
  292.   setvisualpage(0);
  293.   gi.nPageCur = 0;
  294.   InitColorsX();
  295. #ifdef MOUSE
  296.   MouseInit(xPcScreen, yPcScreen);
  297. #endif
  298.   /* Make sure we reset textrows upon restart. */
  299.   gs.nTextRows = abs(gs.nTextRows);
  300. #endif /* BGI */
  301.  
  302. #ifdef MACG
  303.   MaxApplZone();
  304.   InitGraf(&thePort);
  305.   InitFonts();
  306.   FlushEvents(everyEvent, 0);
  307.   InitWindows();
  308.   InitMenus();
  309.   TEInit();
  310.   InitDialogs(0L);
  311.   InitCursor();
  312.  
  313.   gi.rcDrag = screenBits.bounds;
  314.   gi.rcBounds.left = 20;
  315.   gi.rcBounds.top = 20 + GetMBarHeight();
  316.   gi.rcBounds.right = gi.rcBounds.left + gs.xWin;
  317.   gi.rcBounds.bottom = gi.rcBounds.top + gs.yWin;
  318.   gi.wpAst = NewCWindow(0L, &gi.rcBounds, "\pAstrolog 5.30", true,
  319.     noGrowDocProc, (WindowPtr)-1L, true, 0);
  320.   SetPort(gi.wpAst);
  321.   InitColorsX();
  322. #endif /* MACG */
  323. }
  324.  
  325.  
  326. /* Add a certain amount of time to the current hour/day/month/year quantity */
  327. /* defining the present chart. This is used by the chart animation feature. */
  328. /* We can add or subtract anywhere from 1 to 9 seconds, minutes, hours,     */
  329. /* days, months, years, decades, centuries, or millenia in any one call.    */
  330. /* This is mainly just addition to the appropriate quantity, but we have    */
  331. /* to check for overflows, e.g. Dec 30 + 3 days = Jan 2 of Current year + 1 */
  332.  
  333. void AddTime(mode, toadd)
  334. int mode, toadd;
  335. {
  336.   int d;
  337.   real h, m;
  338.  
  339.   if (!FBetween(mode, 1, 9))
  340.     mode = 4;
  341.  
  342.   h = RFloor(TT);
  343.   m = RFract(TT)*100.0;
  344.   if (mode == 1)
  345.     m += 1.0/60.0*(real)toadd;    /* Add seconds. */
  346.   else if (mode == 2)
  347.     m += (real)toadd;             /* add minutes. */
  348.  
  349.   /* Add hours, either naturally or if minute value overflowed. */
  350.  
  351.   if (m < 0.0 || m >= 60.0 || mode == 3) {
  352.     if (m >= 60.0) {
  353.       m -= 60.0; toadd = NSgn(toadd);
  354.     } else if (m < 0.0) {
  355.       m += 60.0; toadd = NSgn(toadd);
  356.     }
  357.     h += (real)toadd;
  358.   }
  359.  
  360.   /* Add days, either naturally or if hour value overflowed. */
  361.  
  362.   if (h >= 24.0 || h < 0.0 || mode == 4) {
  363.     if (h >= 24.0) {
  364.       h -= 24.0; toadd = NSgn(toadd);
  365.     } else if (h < 0.0) {
  366.       h += 24.0; toadd = NSgn(toadd);
  367.     }
  368.     DD = AddDay(MM, DD, YY, toadd);
  369.   }
  370.  
  371.   /* Add months, either naturally or if day value overflowed. */
  372.  
  373.   if (DD > (d = DayInMonth(MM, YY)) || DD < 1 || mode == 5) {
  374.     if (DD > d) {
  375.       DD -= d; toadd = NSgn(toadd);
  376.     } else if (DD < 1) {
  377.       DD += DayInMonth(Mod12(MM - 1), YY);
  378.       toadd = NSgn(toadd);
  379.     }
  380.     MM += toadd;
  381.   }
  382.  
  383.   /* Add years, either naturally or if month value overflowed. */
  384.  
  385.   if (MM > 12 || MM < 1 || mode == 6) {
  386.     if (MM > 12) {
  387.       MM -= 12; toadd = NSgn(toadd);
  388.     } else if (MM < 1) {
  389.       MM += 12; toadd = NSgn(toadd);
  390.     }
  391.     YY += toadd;
  392.   }
  393.   if (mode == 7)
  394.     YY += 10 * toadd;      /* Add decades.   */
  395.   else if (mode == 8)
  396.     YY += 100 * toadd;     /* Add centuries. */
  397.   else if (mode == 9)
  398.     YY += 1000 * toadd;    /* Add millenia.  */
  399.   TT = h+m/100.0;          /* Recalibrate hour time. */
  400. }
  401.  
  402.  
  403. /* Animate the current chart based on the given values indicating how much  */
  404. /* to update by. We update and recast the current chart info appropriately. */
  405. /* Note animation mode for comparison charts will update the second chart.  */
  406.  
  407. void Animate(mode, toadd)
  408. int mode, toadd;
  409. {
  410.   if (gi.nMode == gWorldMap || gi.nMode == gGlobe || gi.nMode == gPolar) {
  411.     gs.nRot += toadd;
  412.     if (gs.nRot >= nDegMax)     /* For animating globe display, add */
  413.       gs.nRot -= nDegMax;       /* in appropriate degree value.     */
  414.     else if (gs.nRot < 0)
  415.       gs.nRot += nDegMax;
  416.   } else {
  417.     if (mode == 10) {
  418. #ifdef TIME
  419.       /* For the continuous chart update to present moment */
  420.       /* animation mode, go get whatever time it is now.   */
  421.       FInputData(szNowCore);
  422. #else
  423.       if (us.nRel <= rcDual)
  424.         ciCore = ciTwin;
  425.       else
  426.         ciCore = ciMain;
  427.       AddTime(1, toadd);
  428. #endif
  429.     } else {  /* Otherwise add on appropriate time vector to chart info. */
  430.       if (us.nRel <= rcDual)
  431.         ciCore = ciTwin;
  432.       else
  433.         ciCore = ciMain;
  434.       AddTime(mode, toadd);
  435.     }
  436.     if (us.nRel <= rcDual) {
  437.       ciTwin = ciCore;
  438.       ciCore = ciMain;
  439.     } else
  440.       ciMain = ciCore;
  441.     if (us.nRel)
  442.       CastRelation();
  443.     else
  444.       CastChart(fTrue);
  445.   }
  446. }
  447.  
  448.  
  449. /* This routine exits graphics mode, prompts the user for a set of command */
  450. /* switches, processes them, and returns to the previous graphics with the */
  451. /* new settings in effect, allowing one to change most any setting without */
  452. /* having to lose their graphics state or fall way back to a -Q loop.      */
  453.  
  454. void CommandLineX()
  455. {
  456.   char szCommandLine[cchSzMax], *rgsz[MAXSWITCHES];
  457.   int argc, fT, fPause = fFalse;
  458.  
  459.   ciCore = ciMain;
  460. #ifdef MSG
  461.   _setvideomode(_DEFAULTMODE);
  462.   _settextrows(gs.nTextRows);
  463. #endif
  464. #ifdef BGI
  465.   restorecrtmode();
  466.   if (gs.nTextRows > 25)
  467.     textmode(C4350);
  468. #endif
  469.   fT = us.fLoop; us.fLoop = fTrue;
  470.   argc = NPromptSwitches(szCommandLine, rgsz);
  471.   is.cchRow = 0;
  472.   is.fSzInteract = fTrue;
  473.   if (!FProcessSwitches(argc, rgsz))
  474.     fPause = fTrue;
  475.   else {
  476.     is.fMult = fFalse;
  477.     FPrintTables();
  478.     if (is.fMult) {
  479.       ClearB((lpbyte)&us.fCredit,
  480.         (int)((lpbyte)&us.fLoop - (lpbyte)&us.fCredit));
  481.       fPause = fTrue;
  482.     }
  483.   }
  484.  
  485. #ifdef PCG
  486.   /* Pause for the user if there was either an error processing the    */
  487.   /* switches, or one of the informational text tables was brought up. */
  488.  
  489.   if (fPause) {
  490.     AnsiColor(kDefault);
  491.     is.cchRow = 0;
  492.     PrintSz("Press any key to return to graphics.\n");
  493.     while (!kbhit())
  494.       ;
  495.     getch();
  496.   }
  497. #endif
  498.   is.fSzInteract = fFalse;
  499.   us.fLoop = fT;
  500.   ciMain = ciCore;
  501.   BeginX();
  502. }
  503.  
  504.  
  505. /* Given two chart size values, adjust them such that the chart will look */
  506. /* "square". We round the higher value down and check certain conditions. */
  507.  
  508. void SquareX(x, y, force)
  509. int *x, *y, force;
  510. {
  511.   if (!force && !fSquare)    /* Unless we want to force a square, realize */
  512.     return;                  /* that some charts look better rectangular. */
  513.   if (*x > *y)
  514.     *x = *y;
  515.   else
  516.     *y = *x;
  517. #ifdef PCG
  518.   if (FEgaRes(gi.nRes))         /* Scale horizontal size if we're in a PC */
  519.     *x = VgaFromEga(*x);        /* graphics mode without "square" pixels. */
  520.   else if (FCgaRes(gi.nRes))
  521.     *x = VgaFromCga(*x);
  522. #endif
  523.   if (fSidebar)      /* Take into account chart's sidebar, if any. */
  524.     *x += xSideT;
  525. }
  526.  
  527.  
  528. #ifndef WIN
  529. /* This routine gets called after graphics are brought up and displayed     */
  530. /* on the screen. It loops, processing key presses, mouse clicks, etc, that */
  531. /* the window receives, until the user specifies they want to exit program. */
  532.  
  533. void InteractX()
  534. {
  535. #ifdef X11
  536.   char sz[cchSzDef];
  537.   XEvent xevent;
  538.   KeySym keysym;
  539.   int fResize = fFalse, fRedraw = fTrue;
  540. #endif
  541. #ifdef PCG
  542. #ifdef MOUSE
  543.   int eventx, eventy, eventbtn;
  544. #endif
  545.   int fResize = fTrue, fRedraw = fFalse;
  546. #endif /* PCG */
  547. #ifdef MACG
  548.   EventRecord erCur;
  549.   WindowPtr wpCur;
  550.   int wc, fEvent, fResize = fFalse, fRedraw = fTrue;
  551. #endif
  552.   int fBreak = fFalse, fPause = fFalse, fCast = fFalse, xcorner = 7,
  553.     mousex = -1, mousey = -1, buttonx = -1, buttony = -1, dir = 1,
  554.     length, key, i;
  555.   bool fT;
  556.   KI coldrw = gi.kiLite;
  557.  
  558.   neg(gs.nAnim);
  559.   while (!fBreak) {
  560.     gi.nScale = gs.nScale/100;
  561.  
  562.     /* Some chart windows, like the world maps and aspect grids, should */
  563.     /* always be a certian size, so correct if a resize was attempted.  */
  564.  
  565.     if (fMap) {
  566.       length = nDegMax*gi.nScale;
  567.       if (gs.xWin != length) {
  568.         gs.xWin = length;
  569.         fResize = fTrue;
  570.       }
  571.       length = nDegHalf*gi.nScale;
  572.       if (gs.yWin != length) {
  573.         gs.yWin = length;
  574.         fResize = fTrue;
  575.       }
  576.     } else if (gi.nMode == gGrid) {
  577.       if (gs.xWin != (length =
  578.         (gs.nGridCell + (us.nRel <= rcDual))*CELLSIZE*gi.nScale+1)) {
  579.         gs.xWin = length;
  580.         fResize = fTrue;
  581.       } if (gs.yWin != length) {
  582.         gs.yWin = length;
  583.         fResize = fTrue;
  584.       }
  585.  
  586.     /* Make sure the window isn't too large or too small. */
  587.  
  588.     } else {
  589.       if (gs.xWin < BITMAPX1) {
  590.         gs.xWin = BITMAPX1;
  591.         fResize = fTrue;
  592.       } else if (gs.xWin > BITMAPX) {
  593.         gs.xWin = BITMAPX;
  594.         fResize = fTrue;
  595.       }
  596.       if (gs.yWin < BITMAPY1) {
  597.         gs.yWin = BITMAPY1;
  598.         fResize = fTrue;
  599.       } else if (gs.yWin > BITMAPY) {
  600.         gs.yWin = BITMAPY;
  601.         fResize = fTrue;
  602.       }
  603.     }
  604.  
  605.     /* If in animation mode, ensure we are in the flicker free resolution. */
  606.  
  607.     if (gs.nAnim < 0) {
  608.       neg(gs.nAnim);
  609. #ifdef PCG
  610.       if (gi.nRes == gs.nResHi && !gs.fJetTrail) {
  611.         gi.nRes = gs.nResLo;
  612.         BeginX();
  613.         gs.xWin = xPcScreen;
  614.         gs.yWin = yPcScreen;
  615.         SquareX(&gs.xWin, &gs.yWin, fFalse);
  616.         fResize = fTrue;
  617.       }
  618. #endif
  619.     }
  620.  
  621.     /* Physically resize window if we've changed the size parameters. */
  622.  
  623.     if (fResize) {
  624.       fResize = fFalse;
  625. #ifdef X11
  626.       XResizeWindow(gi.disp, gi.wind, gs.xWin, gs.yWin);
  627.       XFreePixmap(gi.disp, gi.pmap);
  628.       gi.pmap = XCreatePixmap(gi.disp, gi.wind, gs.xWin, gs.yWin, gi.depth);
  629. #endif
  630. #ifdef PCG
  631.       if (xPcScreen > gs.xWin)
  632.         gi.xOffset = (xPcScreen - gs.xWin) / 2;
  633.       else {
  634.         if (xcorner % 3 == 1)
  635.           gi.xOffset = 0;
  636.         else if (xcorner % 3 == 0)
  637.           gi.xOffset = -gs.xWin + xPcScreen;
  638.         else
  639.           gi.xOffset = -(gs.xWin - xPcScreen) / 2;
  640.       }
  641.       if (yPcScreen > gs.yWin)
  642.         gi.yOffset = (yPcScreen - gs.yWin) / 2;
  643.       else {
  644.         if (xcorner > 6)
  645.           gi.yOffset = 0;
  646.         else if (xcorner < 4)
  647.           gi.yOffset = -gs.yWin + yPcScreen;
  648.         else
  649.           gi.yOffset = -(gs.yWin - yPcScreen) / 2;
  650.       }
  651. #endif
  652. #ifdef MACG
  653.       SizeWindow(gi.wpAst, gs.xWin, gs.yWin, fTrue);
  654. #endif
  655.       fRedraw = fTrue;
  656.     }
  657.  
  658.     /* Recast chart if the chart information has changed any. */
  659.  
  660.     if (fCast) {
  661.       fCast = fFalse;
  662.       ciCore = ciMain;
  663.       if (us.nRel)
  664.         CastRelation();
  665.       else
  666.         CastChart(fTrue);
  667.       fRedraw = fTrue;
  668.     }
  669.     if (gs.nAnim && !fPause)
  670.       fRedraw = fTrue;
  671.  
  672.     /* Update the screen if anything has changed since last time around. */
  673.  
  674.     if (fRedraw && (!fPause || gs.nAnim)) {
  675.       fRedraw = fFalse;
  676.  
  677.       /* If we're in animation mode, change the chart info appropriately. */
  678.  
  679.       if (gs.nAnim && !fPause)
  680.         Animate(gs.nAnim, dir);
  681.  
  682.       /* Clear the screen and set up a buffer to draw in. */
  683.  
  684. #ifdef X11
  685.       XFillRectangle(gi.disp, gi.pmap, gi.pmgc, 0, 0, gs.xWin, gs.yWin);
  686. #endif
  687. #ifdef PCG
  688. #ifdef MOUSE
  689.       MouseShow(fFalse);
  690. #endif
  691. #ifdef MSG
  692.       if (gi.cfg.numvideopages > 1)
  693.         _setactivepage(_getactivepage() == gs.fJetTrail);
  694. #else
  695.       if (gi.nPages > 1) {
  696.         gi.nPageCur = (gi.nPageCur == gs.fJetTrail);
  697.         setactivepage(gi.nPageCur);
  698.       }
  699. #endif
  700. #endif /* PCG */
  701. #ifdef MACG
  702.       SetPort(gi.wpAst);
  703.       InvalRect(&gi.wpAst->portRect);
  704.       BeginUpdate(gi.wpAst);
  705.       EraseRect(&gi.wpAst->portRect);
  706. #endif
  707.  
  708.       DrawChartX();
  709.  
  710.       /* Make the drawn chart visible in the current screen buffer. */
  711.  
  712. #ifdef X11
  713.       XSync(gi.disp, 0);
  714.       XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc,
  715.         0, 0, gs.xWin, gs.yWin, 0, 0);
  716. #endif
  717. #ifdef PCG
  718. #ifdef MSG
  719.       if (gi.cfg.numvideopages > 1)
  720.         _setvisualpage(_getactivepage());
  721. #else
  722.       if (gi.nPages > 1)
  723.         setvisualpage(gi.nPageCur);
  724. #endif
  725. #ifdef MOUSE
  726.       if (!gs.nAnim || fPause)
  727.         MouseShow(fTrue);
  728. #endif
  729. #endif /* PCG */
  730. #ifdef MACG
  731.       EndUpdate(gi.wpAst);
  732. #endif
  733.     }  /* if */
  734.  
  735.     /* Now process what's on the event queue, i.e. any keys pressed, etc. */
  736.  
  737. #ifdef X11
  738.     if (XEventsQueued(gi.disp, QueuedAfterFlush /*QueuedAfterReading*/) ||
  739.       !gs.nAnim || fPause) {
  740.       XNextEvent(gi.disp, &xevent);
  741.  
  742.       /* Restore what's on window if a part of it gets uncovered. */
  743.  
  744.       if (xevent.type == Expose && xevent.xexpose.count == 0) {
  745.         XSync(gi.disp, 0);
  746.         XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc,
  747.           0, 0, gs.xWin, gs.yWin, 0, 0);
  748.       }
  749.       switch (xevent.type) {
  750.  
  751.       /* Check for a manual resize of window by user. */
  752.  
  753.       case ConfigureNotify:
  754.         gs.xWin = xevent.xconfigure.width;
  755.         gs.yWin = xevent.xconfigure.height;
  756.         XFreePixmap(gi.disp, gi.pmap);
  757.         gi.pmap = XCreatePixmap(gi.disp, gi.wind, gs.xWin, gs.yWin, gi.depth);
  758.         fRedraw = fTrue;
  759.         break;
  760.       case MappingNotify:
  761.         XRefreshKeyboardMapping((XMappingEvent *)&xevent);
  762.         break;
  763.  
  764. #ifdef MOUSE
  765.       /* Process any mouse buttons the user pressed. */
  766.  
  767.       case ButtonPress:
  768.         mousex = xevent.xbutton.x; mousey = xevent.xbutton.y;
  769.         if (xevent.xbutton.button == Button1) {
  770.           DrawColor(gi.kiLite);
  771.           DrawPoint(mousex, mousey);
  772.           XSync(gi.disp, 0);
  773.           XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc,
  774.             0, 0, gs.xWin, gs.yWin, 0, 0);
  775.         } else if (xevent.xbutton.button == Button2 && (gi.nMode ==
  776.           gAstroGraph || gi.nMode == gWorldMap) && gs.nRot == 0) {
  777.           Lon = DegToDec(rDegHalf -
  778.             (real)(xevent.xbutton.x-1)/(real)(gs.xWin-2)*rDegMax);
  779.           Lat = DegToDec(rDegQuad -
  780.             (real)(xevent.xbutton.y-1)/(real)(gs.yWin-2)*181.0);
  781.           sprintf(sz, "Mouse is at %s.", SzLocation(Lon, Lat));
  782.           PrintNotice(sz);
  783.         } else if (xevent.xbutton.button == Button3)
  784.           fBreak = fTrue;
  785.         break;
  786.  
  787.       /* Check for user dragging any of the mouse buttons across window. */
  788.  
  789.       case MotionNotify:
  790.         DrawColor(coldrw);
  791.         DrawLine(mousex, mousey, xevent.xbutton.x, xevent.xbutton.y);
  792.         XSync(gi.disp, 0);
  793.         XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc,
  794.           0, 0, gs.xWin, gs.yWin, 0, 0);
  795.         mousex = xevent.xbutton.x; mousey = xevent.xbutton.y;
  796.         break;
  797. #endif
  798.  
  799.       /* Process any keys user pressed in window. */
  800.  
  801.       case KeyPress:
  802.         length = XLookupString((XKeyEvent *)&xevent, xkey, 10, &keysym, 0);
  803.         if (length == 1) {
  804.           key = xkey[0];
  805. #endif /* X11 */
  806.  
  807. #ifdef PCG
  808. #ifdef MOUSE
  809.       if ((!gs.nAnim || fPause) && MouseStatus(&eventx, &eventy, &eventbtn)) {
  810.  
  811.         /* If the left button is down, draw on the screen. */
  812.         if (eventbtn == mfLeft && mousex >= 0) {
  813.           MouseShow(fFalse);
  814.           DrawColor(coldrw);
  815.           PcMoveTo(mousex, mousey);
  816.           buttonx = eventx; buttony = eventy;
  817.           PcLineTo(buttonx, buttony);
  818.  
  819.         /* If the right button is down, change the default location. */
  820.         } else if (eventbtn == mfRight) {
  821.           if (fMap && gs.nRot == 0 && !gs.fConstel && !gs.fMollewide) {
  822.             Lon = DegToDec(rDegHalf-(real)(eventx-gi.xOffset)/
  823.               (real)gs.xWin*rDegMax);
  824.             if (Lon < -rDegHalf)
  825.               Lon = -rDegHalf;
  826.             else if (Lon > rDegHalf)
  827.               Lon = rDegHalf;
  828.             Lat = DegToDec(rDegQuad-(real)(eventy-gi.yOffset)/
  829.               (real)gs.yWin*181.0);
  830.             if (Lat < -rDegQuad)
  831.               Lat = -rDegQuad;
  832.             else if (Lat > rDegQuad)
  833.               Lat = rDegQuad;
  834.             fCast = fTrue;
  835.  
  836.           /* Right button means draw lines if not in a world map mode. */
  837.           } else if (buttonx >= 0) {
  838.             MouseShow(fFalse);
  839.             DrawColor(coldrw);
  840.             PcMoveTo(buttonx, buttony);
  841.             PcLineTo(eventx, eventy);
  842.           }
  843.  
  844.         /* Middle button (which most PC's don't have) means exit program. */
  845.         } else if (eventbtn == mfMiddle)
  846.           fBreak = fTrue;
  847.  
  848.         mousex = eventx; mousey = eventy;
  849.         MouseShow(fTrue);
  850.       } else
  851. #endif /* MOUSE */
  852.         if (kbhit()) {
  853.           key = getch();
  854. #endif /* PCG */
  855.  
  856. #ifdef MACG
  857.       HiliteMenu(0);
  858.       SystemTask();
  859.       fEvent = GetNextEvent(everyEvent, &erCur);
  860.       if (fEvent) {
  861.         switch (erCur.what) {
  862.         case mouseDown:
  863.           wc = FindWindow(erCur.where, &wpCur);
  864.           switch (wc) {
  865.           case inSysWindow:
  866.             SystemClick(&erCur, wpCur);
  867.             break;
  868.           case inMenuBar:
  869.             MenuSelect(erCur.where);
  870.             break;
  871.           case inDrag:
  872.             if (wpCur == gi.wpAst)
  873.               DragWindow(gi.wpAst, erCur.where, &gi.rcDrag);
  874.             break;
  875.           case inContent:
  876.             if (wpCur == gi.wpAst && wpCur != FrontWindow())
  877.               SelectWindow(gi.wpAst);
  878.             break;
  879.           case inGoAway:
  880.             if (wpCur == gi.wpAst && TrackGoAway(gi.wpAst, erCur.where))
  881.               HideWindow(gi.wpAst);
  882.             break;
  883.           }
  884.           break;
  885.         case updateEvt:
  886.           /*fRedraw = fTrue;*/
  887.           break;
  888.         case keyDown:
  889.         case autoKey:
  890.           key = (char)(erCur.message & charCodeMask);
  891. #endif /* MACG */
  892.  
  893. LSwitch:
  894.           switch (key) {
  895. #ifdef PCG
  896.           case chNull:
  897.             key = NFromAltN(getch());
  898.             goto LSwitch;
  899. #endif
  900.           case ' ':
  901.             fRedraw = fTrue;
  902.             break;
  903.           case 'p':
  904.             not(fPause);
  905.             break;
  906.           case 'r':
  907.             neg(dir);
  908.             break;
  909.           case 'x':
  910.             not(gs.fInverse);
  911.             InitColorsX();
  912.             fRedraw = fTrue;
  913.             break;
  914.           case 'm':
  915.             if (!gi.fMono) {
  916.               not(gs.fColor);
  917. #ifdef MSG
  918.               _getvideoconfig((struct videoconfig far *) &gi.cfg);
  919. #endif
  920.               InitColorsX();
  921.               fRedraw = fTrue;
  922.             }
  923.             break;
  924.           case 'B':
  925. #ifdef X11
  926.             XSetWindowBackgroundPixmap(gi.disp, gi.root, gi.pmap);
  927.             XClearWindow(gi.disp, gi.root);
  928. #endif
  929. #ifdef PCG
  930.             gs.xWin = xPcScreen;
  931.             gs.yWin = yPcScreen;
  932.             SquareX(&gs.xWin, &gs.yWin, fFalse);
  933.             fResize = fTrue;
  934. #endif
  935.             break;
  936.           case 't':
  937.             not(gs.fText);
  938.             fRedraw = fTrue;
  939.             break;
  940.           case 'i':
  941.             not(gs.fAlt);
  942.             fRedraw = fTrue;
  943.             break;
  944.           case 'b':
  945.             not(gs.fBorder);
  946.             fRedraw = fTrue;
  947.             break;
  948.           case 'l':
  949.             not(gs.fLabel);
  950.             fRedraw = fTrue;
  951.             break;
  952.           case 'j':
  953.             not(gs.fJetTrail);
  954.             break;
  955.           case '<':
  956.             if (gs.nScale > 100) {
  957.               gs.nScale -= 100;
  958.               fResize = fTrue;
  959.             }
  960.             break;
  961.           case '>':
  962.             if (gs.nScale < MAXSCALE) {
  963.               gs.nScale += 100;
  964.               fResize = fTrue;
  965.             }
  966.             break;
  967.           case '[':
  968.             if (gi.nMode == gGlobe && gs.rTilt > -rDegQuad) {
  969.               gs.rTilt = gs.rTilt > -rDegQuad ? gs.rTilt-TILTSTEP : -rDegQuad;
  970.               fRedraw = fTrue;
  971.             }
  972.             break;
  973.           case ']':
  974.             if (gi.nMode == gGlobe && gs.rTilt < rDegQuad) {
  975.               gs.rTilt = gs.rTilt < rDegQuad ? gs.rTilt+TILTSTEP : rDegQuad;
  976.               fRedraw = fTrue;
  977.             }
  978.             break;
  979.           case 'Q':
  980.             SquareX(&gs.xWin, &gs.yWin, fTrue);
  981.             fResize = fTrue;
  982.             break;
  983.           case 'R':
  984.             for (i = oChi; i <= oVes; i++)
  985.               not(ignore[i]);
  986.             for (i = oLil; i <= oEP; i++)
  987.               not(ignore[i]);
  988.             fCast = fTrue;
  989.             break;
  990.           case 'C':
  991.             not(us.fCusp);
  992.             for (i = cuspLo; i <= cuspHi; i++)
  993.               ignore[i] = !us.fCusp || !ignore[i];
  994.             fCast = fTrue;
  995.             break;
  996.           case 'u':
  997.             not(us.fUranian);
  998.             for (i = uranLo; i <= uranHi; i++)
  999.               ignore[i] = !us.fUranian || !ignore[i];
  1000.             fCast = fTrue;
  1001.             break;
  1002.           case 'U':
  1003.             us.nStar = !us.nStar;
  1004.             for (i = starLo; i <= starHi; i++)
  1005.               ignore[i] = !us.nStar || !ignore[i];
  1006.             fCast = fTrue;
  1007.             break;
  1008.           case 'c':
  1009.             us.nRel = us.nRel ? 0 : rcDual;
  1010.             fCast = fTrue;
  1011.             break;
  1012.           case 's':
  1013.             not(us.fSidereal);
  1014.             fCast = fTrue;
  1015.             break;
  1016.           case 'h':
  1017.             not(us.objCenter);
  1018.             fCast = fTrue;
  1019.             break;
  1020.           case 'f':
  1021.             not(us.fFlip);
  1022.             fCast = fTrue;
  1023.             break;
  1024.           case 'g':
  1025.             not(us.fDecan);
  1026.             fCast = fTrue;
  1027.             break;
  1028.           case '+':
  1029.             Animate(gs.nAnim, abs(dir));
  1030.             fCast = fTrue;
  1031.             break;
  1032.           case '-':
  1033.             Animate(gs.nAnim, -abs(dir));
  1034.             fCast = fTrue;
  1035.             break;
  1036.           case 'o':
  1037.             ciSave = ciMain;
  1038.             break;
  1039.           case 'O':
  1040.             ciMain = ciSave;
  1041.             fCast = fTrue;
  1042.             break;
  1043. #ifdef TIME
  1044.           case 'n':
  1045.             FInputData(szNowCore);
  1046.             ciMain = ciCore;
  1047.             fCast = fTrue;
  1048.             break;
  1049. #endif
  1050.           case 'N':                     /* The continuous update animation. */
  1051.             gs.nAnim = gs.nAnim ? 0 : -10;
  1052.             break;
  1053.  
  1054.           /* These are the nine different "add time to chart" animations. */
  1055.           case '!': gs.nAnim = -1; break;
  1056.           case '@': gs.nAnim = -2; break;
  1057.           case '#': gs.nAnim = -3; break;
  1058.           case '$': gs.nAnim = -4; break;
  1059.           case '%': gs.nAnim = -5; break;
  1060.           case '^': gs.nAnim = -6; break;
  1061.           case '&': gs.nAnim = -7; break;
  1062.           case '*': gs.nAnim = -8; break;
  1063.           case '(': gs.nAnim = -9; break;
  1064.  
  1065.           /* Should we go switch to a new chart type? */
  1066.           case 'V': gi.nMode = gWheel;      fRedraw = fTrue; break;
  1067.           case 'A': gi.nMode = gGrid;       fRedraw = fTrue; break;
  1068.           case 'Z': gi.nMode = gHorizon;    fRedraw = fTrue; break;
  1069.           case 'S': gi.nMode = gOrbit;      fRedraw = fTrue; break;
  1070.           case 'M': gi.nMode = gSector;     fRedraw = fTrue; break;
  1071.           case 'K': gi.nMode = gCalendar;   fRedraw = fTrue; break;
  1072.           case 'J': gi.nMode = gDisposit;   fRedraw = fTrue; break;
  1073.           case 'L': gi.nMode = gAstroGraph; fRedraw = fTrue; break;
  1074.           case 'E': gi.nMode = gEphemeris;  fRedraw = fTrue; break;
  1075.           case 'W': gi.nMode = gWorldMap;   fRedraw = fTrue; break;
  1076.           case 'G': gi.nMode = gGlobe;      fRedraw = fTrue; break;
  1077.           case 'P': gi.nMode = gPolar;      fRedraw = fTrue; break;
  1078. #ifdef BIORHYTHM
  1079.           case 'Y':            /* Should we switch to biorhythm chart? */
  1080.             us.nRel = rcBiorhythm;
  1081.             gi.nMode = gBiorhythm;
  1082.             fCast = fTrue;
  1083.             break;
  1084. #endif
  1085. #ifdef CONSTEL
  1086.           case 'F':
  1087.             if (!fMap && gi.nMode != gGlobe && gi.nMode != gPolar)
  1088.               gi.nMode = gWorldMap;
  1089.             not(gs.fConstel);
  1090.             fRedraw = fTrue;
  1091.             break;
  1092. #endif
  1093.           case '0':
  1094.             not(us.fPrimeVert);
  1095.             not(us.fCalendarYear);
  1096.             not(us.nEphemYears);
  1097.             not(gs.fMollewide);
  1098.             gi.nMode = (gi.nMode == gWheel ? gHouse :
  1099.               (gi.nMode == gHouse ? gWheel : gi.nMode));
  1100.             fRedraw = fTrue;
  1101.             break;
  1102.           case 'v': case 'H': case '?':
  1103. #ifdef MSG
  1104.             _setvideomode(_DEFAULTMODE);
  1105.             if (key != 'v')
  1106.               _settextrows(50);
  1107. #endif
  1108. #ifdef BGI
  1109.             restorecrtmode();
  1110.             if (key != 'v')
  1111.               textmode(C4350);
  1112. #endif
  1113.             length = us.nScrollRow;
  1114.             us.nScrollRow = 0;
  1115.             if (key == 'v')
  1116.               ChartListing();
  1117.             else
  1118.               DisplayKeysX();
  1119.             us.nScrollRow = length;
  1120. #ifdef PCG
  1121.             while (!kbhit())
  1122.               ;
  1123.             key = getch();
  1124.             if (key == 'q' || key == chEscape || key == chBreak) {
  1125.               fBreak = fTrue;
  1126.               break;
  1127.             }
  1128.             BeginX();
  1129.             fResize = fTrue;
  1130. #endif
  1131.             break;
  1132.           case chReturn:
  1133.             CommandLineX();
  1134.             fResize = fCast = fTrue;
  1135.             break;
  1136. #ifdef PCG
  1137.           case chTab:
  1138.             if (gi.nRes == gs.nResHi)
  1139.               gi.nRes = gs.nResLo;
  1140.             else
  1141.               gi.nRes = gs.nResHi;
  1142.             BeginX();
  1143.             gs.xWin = xPcScreen;
  1144.             gs.yWin = yPcScreen;
  1145.             SquareX(&gs.xWin, &gs.yWin, fFalse);
  1146.             fResize = fTrue;
  1147.             break;
  1148. #endif
  1149.           case chDelete:
  1150. #ifdef PCG
  1151. #ifdef MOUSE
  1152.             MouseShow(fFalse);
  1153. #endif
  1154. #endif /* PCG */
  1155.             fT = gs.fJetTrail;
  1156.             gs.fJetTrail = fFalse;
  1157.             DrawClearScreen();
  1158.             gs.fJetTrail = fT;
  1159.             break;
  1160. #ifdef MOUSE
  1161.           case 'z'-'`': coldrw = kBlack;   break;
  1162.           case 'e'-'`': coldrw = kMaroon;  break;
  1163.           case 'f'-'`': coldrw = kDkGreen; break;
  1164.           case 'o'-'`': coldrw = kOrange;  break;
  1165.           case 'n'-'`': coldrw = kDkBlue;  break;
  1166.           case 'u'-'`': coldrw = kPurple;  break;
  1167.           case 'k'-'`': coldrw = kDkCyan;  break;
  1168.           case 'l'-'`': coldrw = kLtGray;  break;
  1169.           case 'd'-'`': coldrw = kDkGray;  break;
  1170.           case 'r'-'`': coldrw = kRed;     break;
  1171.           case 'g'-'`': coldrw = kGreen;   break;
  1172.           case 'y'-'`': coldrw = kYellow;  break;
  1173.           case 'b'-'`': coldrw = kBlue;    break;
  1174.           case 'v'-'`': coldrw = kMagenta; break;
  1175.           case 'j'-'`': coldrw = kCyan;    break;
  1176.           case 'a'-'`': coldrw = kWhite;   break;
  1177. #ifdef PCG
  1178.           case 't'-'`':
  1179.             MouseShow(fFalse);
  1180.             if (buttonx >= 0)
  1181. #ifdef MSG
  1182.               _rectangle(_GBORDER, buttonx, buttony, mousex, mousey);
  1183. #else
  1184.               DrawEdge(Min(buttonx, mousex) - gi.xOffset,
  1185.                 Min(buttony, mousey) - gi.yOffset,
  1186.                 Max(mousex, buttonx) - gi.xOffset,
  1187.                 Max(mousey, buttony) - gi.yOffset);
  1188. #endif
  1189.             MouseShow(fTrue);
  1190.             break;
  1191.           case 'x'-'`':
  1192.             MouseShow(fFalse);
  1193.             if (buttonx >= 0)
  1194. #ifdef MSG
  1195.               _ellipse(_GBORDER, buttonx, buttony, mousex, mousey);
  1196. #else
  1197.               DrawEllipse(Min(buttonx, mousex) - gi.xOffset,
  1198.                 Min(buttony, mousey) - gi.yOffset,
  1199.                 Max(mousex, buttonx) - gi.xOffset,
  1200.                 Max(mousey, buttony) - gi.yOffset);
  1201. #endif
  1202.             MouseShow(fTrue);
  1203.             break;
  1204. #endif /* PCG */
  1205. #endif /* MOUSE */
  1206.           case 'q': case chEscape: case chBreak:
  1207.             fBreak = fTrue;
  1208.             break;
  1209.           default:
  1210.             if (key > '0' && key <= '9') {
  1211. #ifdef PCG
  1212.               if (gs.nAnim && !fPause)
  1213. #endif
  1214.                 /* Process numbers 1..9 signifying animation rate. */
  1215.                 dir = (dir > 0 ? 1 : -1)*(key-'0');
  1216. #ifdef PCG
  1217.               else {
  1218.                 /* If we aren't in animation mode, then 1..9 refers to the */
  1219.                 /* clipping "quadrant" to use if chart size > screen size. */
  1220.                 xcorner = key-'0';
  1221.                 fResize = fTrue;
  1222.               }
  1223. #endif
  1224.               break;
  1225.             } else if (FBetween(key, 201, 248)) {
  1226.               is.fSzInteract = fTrue;
  1227.               if (szMacro[key-201]) {
  1228.                 FProcessCommandLine(szMacro[key-201]);
  1229.                 fResize = fCast = fTrue;
  1230.               }
  1231.               is.fSzInteract = fFalse;
  1232.               break;
  1233.             }
  1234.             putchar(chBell);    /* Any key not bound will sound a beep. */
  1235.           }  /* switch */
  1236.         }  /* if */
  1237. #ifdef X11
  1238.       default:
  1239.         ;
  1240.       }  /* switch */
  1241.     }  /* if */
  1242. #endif
  1243. #ifdef MACG
  1244.     }  /* if */
  1245. #endif
  1246.   }  /* while */
  1247. }
  1248.  
  1249.  
  1250. /* This is called right before program termination to get rid of the window. */
  1251.  
  1252. void EndX()
  1253. {
  1254. #ifdef X11
  1255.   XFreeGC(gi.disp, gi.gc);
  1256.   XFreeGC(gi.disp, gi.pmgc);
  1257.   XFreePixmap(gi.disp, gi.pmap);
  1258.   XDestroyWindow(gi.disp, gi.wind);
  1259.   XCloseDisplay(gi.disp);
  1260. #endif
  1261. #ifdef MSG
  1262.   _setvideomode(_DEFAULTMODE);
  1263. #endif
  1264. #ifdef BGI
  1265.   restorecrtmode();
  1266. #endif
  1267. #ifdef MACG
  1268.   DisposeWindow(gi.wpAst);
  1269. #endif
  1270. }
  1271. #endif /* ISG */
  1272. #endif /* WIN */
  1273.  
  1274.  
  1275. /*
  1276. ******************************************************************************
  1277. ** Main Graphics Processing.
  1278. ******************************************************************************
  1279. */
  1280.  
  1281. /* Process one command line switch passed to the program dealing with the    */
  1282. /* graphics features. This is just like the processing of each switch in the */
  1283. /* main program, however here each switch has been prefixed with an 'X'.     */
  1284.  
  1285. int NProcessSwitchesX(argc, argv, pos, fOr, fAnd, fNot)
  1286. int argc, pos;
  1287. bool fOr, fAnd, fNot;
  1288. char **argv;
  1289. {
  1290.   int darg = 0, i, j;
  1291.   real rT;
  1292.   char ch1;
  1293.  
  1294.   ch1 = argv[0][pos+1];
  1295.   switch (argv[0][pos]) {
  1296.   case chNull:
  1297.     break;
  1298.  
  1299.   case 'b':
  1300.     if (us.fNoWrite || is.fSzInteract) {
  1301.       ErrorArgv("Xb");
  1302.       return tcError;
  1303.     }
  1304.     ch1 = ChCap(ch1);
  1305.     if (FValidBmpmode(ch1))
  1306.       gs.chBmpMode = ch1;
  1307.     SwitchF2(gs.fBitmap);
  1308.     gs.fPS = gs.fMeta = fFalse;
  1309.     break;
  1310.  
  1311. #ifdef PS
  1312.   case 'p':
  1313.     if (us.fNoWrite || is.fSzInteract) {
  1314.       ErrorArgv("Xp");
  1315.       return tcError;
  1316.     }
  1317.     gs.fPS = fTrue + (ch1 != '0');
  1318.     gs.fBitmap = gs.fMeta = fFalse;
  1319.     break;
  1320. #endif
  1321.  
  1322. #ifdef META
  1323.   case 'M':
  1324.     if (us.fNoWrite || is.fSzInteract) {
  1325.       ErrorArgv("XM");
  1326.       return tcError;
  1327.     }
  1328.     if (ch1 == '0')
  1329.       SwitchF(gs.fFont);
  1330.     SwitchF2(gs.fMeta);
  1331.     gs.fBitmap = gs.fPS = fFalse;
  1332.     break;
  1333. #endif
  1334.  
  1335.   case 'o':
  1336.     if (us.fNoWrite || is.fSzInteract) {
  1337.       ErrorArgv("Xo");
  1338.       return tcError;
  1339.     }
  1340.     if (argc <= 1) {
  1341.       ErrorArgc("Xo");
  1342.       return tcError;
  1343.     }
  1344.     if (!gs.fBitmap && !gs.fPS && !gs.fMeta)
  1345.       gs.fBitmap = fTrue;
  1346.     gi.szFileOut = SzPersist(argv[1]);
  1347.     darg++;
  1348.     break;
  1349.  
  1350. #ifdef X11
  1351.   case 'B':
  1352.     if (is.fSzInteract) {
  1353.       ErrorArgv("XB");
  1354.       return tcError;
  1355.     }
  1356.     SwitchF(gs.fRoot);
  1357.     break;
  1358. #endif
  1359.  
  1360.   case 'm':
  1361.     SwitchF(gs.fColor);
  1362.     break;
  1363.  
  1364.   case 'r':
  1365.     SwitchF(gs.fInverse);
  1366.     break;
  1367.  
  1368.   case 'w':
  1369.     if (argc <= 1) {
  1370.       ErrorArgc("Xw");
  1371.       return tcError;
  1372.     }
  1373.     i = atoi(argv[1]);
  1374.     if (argc > 2 && ((j = atoi(argv[2])) || argv[2][0] == '0')) {
  1375.       argc--; argv++;
  1376.       darg++;
  1377.     } else
  1378.       j = i;
  1379.     if (!FValidGraphx(i)) {
  1380.       ErrorValN("Xw", i);
  1381.       return tcError;
  1382.     }
  1383.     if (!FValidGraphy(j)) {
  1384.       ErrorValN("Xw", j);
  1385.       return tcError;
  1386.     }
  1387.     gs.xWin = i; gs.yWin = j;
  1388.     darg++;
  1389.     break;
  1390.  
  1391.   case 's':
  1392.     if (argc <= 1) {
  1393.       ErrorArgc("Xs");
  1394.       return tcError;
  1395.     }
  1396.     i = atoi(argv[1]);
  1397.     if (i < 100)
  1398.       i *= 100;
  1399.     if (!FValidScale(i)) {
  1400.       ErrorValN("Xs", i);
  1401.       return tcError;
  1402.     }
  1403.     gs.nScale = i;
  1404.     darg++;
  1405.     break;
  1406.  
  1407.   case 'i':
  1408.     SwitchF(gs.fAlt);
  1409.     break;
  1410.  
  1411.   case 't':
  1412.     SwitchF(gs.fText);
  1413.     break;
  1414.  
  1415.   case 'u':
  1416.     SwitchF(gs.fBorder);
  1417.     break;
  1418.  
  1419.   case 'l':
  1420.     SwitchF(gs.fLabel);
  1421.     break;
  1422.  
  1423.   case 'j':
  1424.     SwitchF(gs.fJetTrail);
  1425.     break;
  1426.  
  1427.   case '1':
  1428.     if (argc <= 1) {
  1429.       ErrorArgc("X1");
  1430.       return tcError;
  1431.     }
  1432.     i = NParseSz(argv[1], pmObject);
  1433.     if (!FItem(i)) {
  1434.       ErrorValN("X1", i);
  1435.       return tcError;
  1436.     }
  1437.     gs.objLeft = i;
  1438.     darg++;
  1439.     break;
  1440.  
  1441.   case '2':
  1442.     if (argc <= 1) {
  1443.       ErrorArgc("X2");
  1444.       return tcError;
  1445.     }
  1446.     i = NParseSz(argv[1], pmObject);
  1447.     if (!FItem(i)) {
  1448.       ErrorValN("X2", i);
  1449.       return tcError;
  1450.     }
  1451.     gs.objLeft = -i;
  1452.     darg++;
  1453.     break;
  1454.  
  1455. #ifdef X11
  1456.   case 'd':
  1457.     if (is.fSzInteract) {
  1458.       ErrorArgv("Xd");
  1459.       return tcError;
  1460.     }
  1461.     if (argc <= 1) {
  1462.       ErrorArgc("Xd");
  1463.       return tcError;
  1464.     }
  1465.     gs.szDisplay = SzPersist(argv[1]);
  1466.     darg++;
  1467.     break;
  1468. #endif
  1469.  
  1470.   case 'W':
  1471.     if (argc > 1 && ((i = atoi(argv[1])) || argv[1][0] == '0')) {
  1472.       darg++;
  1473.       if (!FValidRotation(i)) {
  1474.         ErrorValN("XW", i);
  1475.         return tcError;
  1476.       }
  1477.       gs.nRot = i;
  1478.     }
  1479.     gi.nMode = gWorldMap;
  1480.     if (ch1 == '0')
  1481.       gs.fMollewide = fTrue;
  1482.     is.fHaveInfo = fTrue;
  1483.     break;
  1484.  
  1485.   case 'G':
  1486.     if (argc > 1 && ((i = atoi(argv[1])) || argv[1][0] == '0')) {
  1487.       darg++;
  1488.       if (!FValidRotation(i)) {
  1489.         ErrorValN("XG", i);
  1490.         return tcError;
  1491.       }
  1492.       gs.nRot = i;
  1493.       if (argc > 2 && ((rT = atof(argv[2])) || argv[2][0] == '0')) {
  1494.         darg++;
  1495.         if (!FValidTilt(rT)) {
  1496.           ErrorValR("XG", rT);
  1497.           return tcError;
  1498.         }
  1499.         gs.rTilt = rT;
  1500.       }
  1501.     }
  1502.     gi.nMode = gGlobe;
  1503.     is.fHaveInfo = fTrue;
  1504.     break;
  1505.  
  1506.   case 'P':
  1507.     if (argc > 1 && ((i = atoi(argv[1])) || argv[1][0] == '0')) {
  1508.       darg++;
  1509.       if (!FValidRotation(i)) {
  1510.         ErrorValN("XP", i);
  1511.         return tcError;
  1512.       }
  1513.     } else
  1514.       i = 0;
  1515.     gs.nRot = i;
  1516.     gi.nMode = gPolar;
  1517.     if (ch1 == '0')
  1518.       gs.fPrintMap = fTrue;
  1519.     is.fHaveInfo = fTrue;
  1520.     break;
  1521.  
  1522. #ifdef CONSTEL
  1523.   case 'F':
  1524.     if (!fMap && gi.nMode != gGlobe && gi.nMode != gPolar)
  1525.       gi.nMode = gWorldMap;
  1526.     not(gs.fConstel);
  1527.     is.fHaveInfo = fTrue;
  1528.     break;
  1529. #endif
  1530.  
  1531. #ifdef ISG
  1532.   case 'n':
  1533.     if (argc > 1 && (i = atoi(argv[1])))
  1534.       darg++;
  1535.     else
  1536.       i = 10;
  1537.     if (i < 1 || i > 10) {
  1538.       ErrorValN("Xn", i);
  1539.       return tcError;
  1540.     }
  1541.     gs.nAnim = i;
  1542.     break;
  1543. #endif
  1544.  
  1545.   default:
  1546.     ErrorSwitch(argv[0]);
  1547.     return tcError;
  1548.   }
  1549.   /* 'darg' contains the value to be added to argc when we return. */
  1550.   return darg;
  1551. }
  1552.  
  1553.  
  1554. /* Process one command line switch passed to the program dealing with more  */
  1555. /* obscure graphics options. This is structured very much like the function */
  1556. /* NProcessSwitchesX(), except here we know each switch begins with 'YX'.   */
  1557.  
  1558. int NProcessSwitchesRareX(argc, argv, pos)
  1559. int argc, pos;
  1560. char **argv;
  1561. {
  1562.   int darg = 0, i;
  1563. #ifdef PS
  1564.   char ch1;
  1565.  
  1566.   ch1 = argv[0][pos+1];
  1567. #endif
  1568.   switch (argv[0][pos]) {
  1569.   case chNull:
  1570.     if (argc <= 2) {
  1571.       ErrorArgc("YX");
  1572.       return tcError;
  1573.     }
  1574. #ifdef PCG
  1575.     i = atoi(argv[1]);
  1576.     if (!FValidResmode(i)) {
  1577.       ErrorValN("YX", i);
  1578.       return tcError;
  1579.     }
  1580.     gs.nResHi = i;
  1581.     i = atoi(argv[2]);
  1582.     if (!FValidResmode(i)) {
  1583.       ErrorValN("YX", i);
  1584.       return tcError;
  1585.     }
  1586.     gs.nResLo = i;
  1587.     gs.fBitmap = gs.fPS = gs.fMeta = fFalse;
  1588. #endif
  1589.     darg += 2;
  1590.     break;
  1591.  
  1592.   case 'G':
  1593.     if (argc <= 1) {
  1594.       ErrorArgc("YXG");
  1595.       return tcError;
  1596.     }
  1597.     i = atoi(argv[1]);
  1598.     if (!FValidGlyphs(i)) {
  1599.       ErrorValN("YXg", i);
  1600.       return tcError;
  1601.     }
  1602.     gs.nGlyphs = i;
  1603.     darg++;
  1604.     break;
  1605.  
  1606.   case 'g':
  1607.     if (argc <= 1) {
  1608.       ErrorArgc("YXg");
  1609.       return tcError;
  1610.     }
  1611.     i = atoi(argv[1]);
  1612.     if (!FValidGrid(i)) {
  1613.       ErrorValN("YXg", i);
  1614.       return tcError;
  1615.     }
  1616.     gs.nGridCell = i;
  1617.     darg++;
  1618.     break;
  1619.  
  1620.   case 'f':
  1621.     if (argc <= 1) {
  1622.       ErrorArgc("YXf");
  1623.       return tcError;
  1624.     }
  1625.     gs.fFont = atoi(argv[1]);
  1626.     darg++;
  1627.     break;
  1628.  
  1629. #ifdef PS
  1630.   case 'p':
  1631.     if (ch1 == '0') {
  1632.       if (argc <= 2) {
  1633.         ErrorArgc("YXp0");
  1634.         return tcError;
  1635.       }
  1636.       gs.xInch = atof(argv[1]);
  1637.       gs.yInch = atof(argv[2]);
  1638.       darg += 2;
  1639.       break;
  1640.     }
  1641.     if (argc <= 1) {
  1642.       ErrorArgc("YXp");
  1643.       return tcError;
  1644.     }
  1645.     gs.nOrient = atoi(argv[1]);
  1646.     darg++;
  1647.     break;
  1648. #endif
  1649.  
  1650.   default:
  1651.     ErrorSwitch(argv[0]);
  1652.     return tcError;
  1653.   }
  1654.   /* 'darg' contains the value to be added to argc when we return. */
  1655.   return darg;
  1656. }
  1657.  
  1658.  
  1659. /* This is the main interface to all the graphics features. This routine     */
  1660. /* is called from the main program if any of the -X switches were specified, */
  1661. /* and it sets up for and goes and generates the appropriate graphics chart. */
  1662. /* We return fTrue if successfull, fFalse if some non-fatal error occurred.  */
  1663.  
  1664. bool FActionX()
  1665. {
  1666.   gi.fFile = (gs.fBitmap || gs.fPS || gs.fMeta);
  1667. #ifdef PS
  1668.   gi.fEps = gs.fPS > fTrue;
  1669. #endif
  1670.  
  1671.   /* First figure out what graphic mode to generate the chart in, based on */
  1672.   /* various non-X command switches, e.g. -L combined with -X, -g combined */
  1673.   /* with -X, and so on, and determine the size the window is to be, too.  */
  1674.  
  1675.   if (gi.nMode == 0) {
  1676.     if (us.fWheel)
  1677.       gi.nMode = gHouse;
  1678.     else if (us.fGrid || us.fMidpoint)
  1679.       gi.nMode = gGrid;
  1680.     else if (us.fHorizon)
  1681.       gi.nMode = gHorizon;
  1682.     else if (us.fOrbit)
  1683.       gi.nMode = gOrbit;
  1684.     else if (us.fSector)
  1685.       gi.nMode = gSector;
  1686.     else if (us.fInfluence)
  1687.       gi.nMode = gDisposit;
  1688.     else if (us.fAstroGraph)
  1689.       gi.nMode = gAstroGraph;
  1690.     else if (us.fCalendar)
  1691.       gi.nMode = gCalendar;
  1692.     else if (us.fEphemeris)
  1693.       gi.nMode = gEphemeris;
  1694.     else if (us.nRel == rcBiorhythm)
  1695.       gi.nMode = gBiorhythm;
  1696.     else
  1697.       gi.nMode = gWheel;
  1698.   }
  1699.   if (gi.nMode == gGrid) {
  1700.     if (us.nRel <= rcDual && us.fMidpoint && !us.fAspList)
  1701.       us.fGridConfig = fTrue;
  1702.     gs.xWin = gs.yWin =
  1703.       (gs.nGridCell + (us.nRel <= rcDual))*CELLSIZE*gi.nScale + 1;
  1704.   } else if (fMap) {
  1705.     gs.xWin = nDegMax*gi.nScale;
  1706.     gs.yWin = nDegHalf*gi.nScale;
  1707.   }
  1708. #ifdef WIN
  1709.   if (fSidebar)
  1710.     gs.xWin -= SIDESIZE;
  1711. #endif
  1712.   gi.nScaleT = gs.fPS ? PSMUL : (gs.fMeta ? METAMUL : 1);
  1713. #ifdef WIN
  1714.   if (wi.hdcPrint != hdcNil)
  1715.     gi.nScaleT = METAMUL;
  1716. #endif
  1717.  
  1718.   if (gi.fFile) {
  1719.     if (gs.xWin == 0)
  1720.       gs.xWin = DEFAULTX;
  1721.     if (gs.yWin == 0)
  1722.       gs.yWin = DEFAULTY;
  1723.     if (fSidebar)
  1724.       gs.xWin += SIDESIZE;
  1725.     if (gs.xWin > BITMAPX)
  1726.       gs.xWin = BITMAPX;
  1727.     if (gs.yWin > BITMAPY)
  1728.       gs.yWin = BITMAPY;
  1729.     BeginFileX();
  1730.     if (gs.fBitmap) {
  1731.       gi.cbBmpRow = (gs.xWin + 1) >> 1;
  1732.       gi.yBand = gs.yWin;
  1733.       if (!FEnsureGrid())
  1734.         return fFalse;
  1735.       while ((gi.bm = PAllocate((long)gi.cbBmpRow * gi.yBand, fTrue, NULL)) ==
  1736.         NULL) {
  1737.         PrintWarning("The bitmap must be generated in multiple stages.");
  1738.         gi.yBand = (gi.yBand + 1) / 2;
  1739.         if (gi.yBand < 1 || gs.chBmpMode != 'B')
  1740.           return fFalse;
  1741.       }
  1742.       if (gi.yBand == gs.yWin)
  1743.         gi.yBand = 0;
  1744.       else {
  1745.         gi.yOffset = gs.yWin - gs.yWin % gi.yBand;
  1746.         if (gi.yOffset == gs.yWin)
  1747.           gi.yOffset -= gi.yBand;
  1748.       }
  1749.     }
  1750. #ifdef PS
  1751.     else if (gs.fPS)
  1752.       PsBegin();
  1753. #endif
  1754. #ifdef META
  1755.     else {
  1756.       if (!FEnsureGrid())
  1757.         return fFalse;
  1758.       for (gi.cbMeta = MAXMETA; gi.cbMeta > 0 &&
  1759.         (gi.bm = PAllocate(gi.cbMeta, fTrue, NULL)) == NULL;
  1760.         gi.cbMeta -= MAXMETA/8)
  1761.         PrintWarning("Attempting to get maximum memory for metafile.");
  1762.       if (gi.cbMeta == 0)
  1763.         return fFalse;
  1764.       gs.xWin   *= METAMUL;  /* Increase chart sizes and scales behind the */
  1765.       gs.yWin   *= METAMUL;  /* scenes to make graphics look smoother.     */
  1766.       gs.nScale *= METAMUL;
  1767.     }
  1768. #endif
  1769.     InitColorsX();
  1770.   }
  1771. #ifdef ISG
  1772.   else {
  1773. #ifdef PCG
  1774.     BeginX();
  1775.     if (gs.xWin == 0 || gs.yWin == 0) {
  1776.       if (gs.xWin == 0)
  1777.         gs.xWin = xPcScreen;
  1778.       if (gs.yWin == 0)
  1779.         gs.yWin = yPcScreen;
  1780.       SquareX(&gs.xWin, &gs.yWin, fFalse);
  1781.     } else if (fSidebar)
  1782.       gs.xWin += SIDESIZE;
  1783. #else
  1784.     if (gs.xWin == 0 || gs.yWin == 0) {
  1785.       if (gs.xWin == 0)
  1786.         gs.xWin = DEFAULTX;
  1787.       if (gs.yWin == 0)
  1788.         gs.yWin = DEFAULTY;
  1789.       SquareX(&gs.xWin, &gs.yWin, fFalse);
  1790.     } else if (fSidebar)
  1791.       gs.xWin += SIDESIZE;
  1792.     BeginX();
  1793. #endif
  1794.   }
  1795. #endif /* ISG */
  1796.  
  1797.   if (gi.fFile || gs.fRoot)    /* Go draw the graphic chart. */
  1798.     DrawChartX();
  1799.   if (gi.fFile) {    /* Write bitmap to file if in that mode. */
  1800.     EndFileX();
  1801.     while (gi.yBand) {
  1802.       gi.yOffset -= gi.yBand;
  1803.       DrawChartX();
  1804.       EndFileX();
  1805.     }
  1806.     if (!gs.fPS)
  1807.       DeallocateHuge(gi.bm);
  1808.   }
  1809. #ifdef ISG
  1810.   else {
  1811. #ifdef X11
  1812.     if (gs.fRoot) {                                         /* Process -XB. */
  1813.       XSetWindowBackgroundPixmap(gi.disp, gi.root, gi.pmap);
  1814.       XClearWindow(gi.disp, gi.root);
  1815.  
  1816.       /* If -Xn in effect with -XB, then enter infinite loop where we */
  1817.       /* calculate and animate chart, displaying on the root window.  */
  1818.       while (gs.nAnim) {
  1819.         Animate(gs.nAnim, 1);
  1820.         if (!gs.fJetTrail)
  1821.           XFillRectangle(gi.disp, gi.pmap, gi.pmgc, 0, 0, gs.xWin, gs.yWin);
  1822.         DrawChartX();
  1823.         XSetWindowBackgroundPixmap(gi.disp, gi.root, gi.pmap);
  1824.         XClearWindow(gi.disp, gi.root);
  1825.       }
  1826.     } else
  1827. #endif
  1828. #ifndef WIN
  1829.       InteractX();    /* Window's up; process commands given to window now. */
  1830.     EndX();
  1831. #else
  1832.     DrawChartX();
  1833. #endif
  1834.   }
  1835. #endif /* ISG */
  1836.   return fTrue;
  1837. }
  1838. #endif /* GRAPH */
  1839.  
  1840. /* xscreen.c */
  1841.